package store.lunangangster.nodeflow.parser.base;

import cn.hutool.core.collection.CollUtil;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import store.lunangangster.nodeflow.builder.entity.ChainProp;
import store.lunangangster.nodeflow.exception.RuleSourceParseException;
import store.lunangangster.nodeflow.parser.FlowParser;
import store.lunangangster.nodeflow.parser.helper.ParserHelper;

/**
 * 解析Xml规则文件的抽象解析器。所有解析Xml规则文件的解析器都需要继承这个类， 并且实现其parseChain方法
 * @author cwk
 * @version 1.0
 */
public abstract class XmlFlowParser implements FlowParser {

  /**
   * 解析Xml文本
   * @param content Xml文本内容
   * @throws RuleSourceParseException 解析错误时抛出
   */
  @Override
  public void parse(String content) throws RuleSourceParseException {
    this.parse(CollUtil.toList(content));
  }

  /**
   * 解析Xml文本列表
   * @param contents Xml文本内容列表
   * @throws RuleSourceParseException 解析错误时抛出
   */
  @Override
  public void parse(List<String> contents) throws RuleSourceParseException {
    if (CollUtil.isEmpty(contents)) {
      return;
    }
    List<Document> documents = new ArrayList<>(contents.size());
    try {
      for (String content : contents) {
        documents.add(DocumentHelper.parseText(content));
      }
      ParserHelper.parseNodes(documents);
      ParserHelper.parseChains(documents, this::parseChain);
    } catch (DocumentException e) {
      throw new RuleSourceParseException("Rule Source parse error", e);
    }
  }

  /**
   * 解析单个以{@link Element}表示的chain
   * @param chainElement &lt;chain&gt;标签对应的{@link Element}对象
   * @return 返回ChainProp传播对象，方便后续生成Chain
   * @throws RuleSourceParseException 解析错误时抛出
   */
  public abstract ChainProp parseChain(Element chainElement) throws RuleSourceParseException;
}
